﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Helpers;
using DataModel;
using System.Windows.Input;
using System.Windows.Controls;
using System.Collections.ObjectModel;
using System.Windows.Media;
using System.IO;
using System.Windows.Media.Imaging;
using System.ComponentModel.Composition;
using Interfaces;

namespace Shelfmanager
{
    [Export(typeof(BookViewModel))]
    public class BookViewModel : NotifyPropertyChangedBase
    {
        [ImportMany(typeof(IBookSearch))]
        IEnumerable<Lazy<IBookSearch, ISearchBookMetadata>> SearchPlugins;

        ObservableCollection<Book> _booksFound;
        public ObservableCollection<Book> BooksFound
        {
            get { return _booksFound; }
            set
            {
                _booksFound = value;
                NotifyPropertyChanged("BooksFound");
            }
        }

        string _isbn;
        public string ISBN
        {
            get { return _isbn; }
            set
            {
                _isbn = value;
                SearchBook(_isbn, "");
                NotifyPropertyChanged("ISBN");
            }
        }

        string _asin;
        public string ASIN
        {
            get { return _asin; }
            set
            {
                _asin = value;
                NotifyPropertyChanged("ASIN");
            }
        }

        string _title;
        public string Title
        {
            get { return _title; }
            set
            {
                _title = value;
                NotifyPropertyChanged("Title");
            }
        }

        ObservableCollection<Author> _authors;
        public ObservableCollection<Author> Authors
        {
            get { return _authors; }
            set
            {
                _authors = value;
                NotifyPropertyChanged("Authors");
            }
        }

        string _publisher;
        public string Publisher
        {
            get { return _publisher; }
            set
            {
                _publisher = value;
                NotifyPropertyChanged("Publisher");
            }
        }

        string _binding;
        public string Binding
        {
            get { return _binding; }
            set
            {
                _binding = value;
                NotifyPropertyChanged("Binding");
            }
        }

        int? _numberOfPages;
        public int? NumberOfPages
        {
            get { return _numberOfPages; }
            set
            {
                _numberOfPages = value;
                NotifyPropertyChanged("NumberOfPages");
            }
        }

        string _publicationDate;
        public string PublicationDate
        {
            get { return _publicationDate; }
            set
            {
                _publicationDate = value;
                NotifyPropertyChanged("PublicationDate");
            }
        }

        string _detailPageUrl;
        public string DetailPageUrl
        {
            get { return _detailPageUrl; }
            set
            {
                _detailPageUrl = value;
                NotifyPropertyChanged("DetailPageUrl");
            }
        }

        string _languageOriginal;
        public string LanguageOriginal
        {
            get { return _languageOriginal; }
            set
            {
                _languageOriginal = value;
                NotifyPropertyChanged("LanguageOriginal");
            }
        }

        string _languagePublished;
        public string LanguagePublished
        {
            get { return _languagePublished; }
            set
            {
                _languagePublished = value;
                NotifyPropertyChanged("LanguagePublished");
            }
        }

        string _subject;
        public string Subject
        {
            get { return _subject; }
            set
            {
                _subject = value;
                NotifyPropertyChanged("Subject");
            }
        }

        int _class;
        public int Class
        {
            get { return _class; }
            set
            {
                _class = value;
                NotifyPropertyChanged("Class");
            }
        }

        string _newAuthor;
        public string NewAuthor
        {
            get { return _newAuthor; }
            set
            {
                _newAuthor = value;
                NotifyPropertyChanged("NewAuthor");
            }
        }

        string _imageUrl;
        public string ImageUrl
        {
            get { return _imageUrl; }
            set
            {
                _imageUrl = value;
                NotifyPropertyChanged("ImageUrl");
                NotifyPropertyChanged("Image");
            }
        }

        public ImageSource Image
        {
            get
            {
                if (_imageUrl != null && _imageUrl != "")
                {
                    return new BitmapImage(new Uri(_imageUrl));
                }
                return null;

            }
        }

        RelayCommand _searchTitleCommand;
        public ICommand SearchTitleCommand
        {
            get
            {
                if (_searchTitleCommand == null)
                {
                    _searchTitleCommand = new RelayCommand(param => this.SearchTitle(), param => this.CanSearchTitle);
                }
                return _searchTitleCommand;
            }
        }

        public void SearchTitle()
        {
            SearchBook("", this.Title);
        }

        public bool CanSearchTitle
        {
            get
            {
                return this.Title != null && this.Title.Length > 3;
            }
        }

        RelayCommand _addAuthorCommand;
        public ICommand AddAuthorCommand
        {
            get
            {
                if (_addAuthorCommand == null)
                {
                    _addAuthorCommand = new RelayCommand(
                        param => this.AddAuthor(),
                        param => this.CanAddAuthor);
                }
                return _addAuthorCommand;
            }
        }

        public void AddAuthor()
        {
            var a = AddAuthor(_newAuthor);
            NewAuthor = "";
            Authors.Add(a);
            NotifyPropertyChanged("Authors");
        }

        public Author AddAuthor(string author)
        {
            DataLayer data = DataLayer.Data;
            Author a = data.Authors.Where(x => x.Name == author).FirstOrDefault();
            if (a == null)
                a = new Author { Name = author };
            return a;
        }

        public Publisher AddPublisher(string publisher)
        {
            DataLayer data = DataLayer.Data;
            Publisher p = data.Publishers.Where(x => x.Name == publisher).FirstOrDefault();
            if (p == null)
                p = new Publisher { Name = publisher };
            return p;
        }

        public bool CanAddAuthor { get { return _newAuthor != ""; } }

        public void SearchBook(string isbn, string title)
        {
            foreach (var s in SearchPlugins.OrderBy(x => x.Metadata.Rank))
            {
                var books = s.Value.Search(isbn, title);
                if (books != null && books.Count() > 0)
                {
                    BooksFound = new ObservableCollection<Book>(books);
                    Title = books[0].Title;
                    NumberOfPages = books[0].NumberOfPages;
                    PublicationDate = books[0].PublicationDate;
                    Publisher = books[0].Publisher.Name;
                    Authors = new ObservableCollection<Author>(books[0].Authors);
                    DetailPageUrl = books[0].DetailPageUrl;
                    ImageUrl = books[0].Image;
                    return;
                }
            }
            BooksFound = null;
        }

        public BookViewModel()
        {
            Logger.Write("BookViewModel()");
            Authors = new ObservableCollection<Author>();
        }

        public Book NewBook()
        {
            NewAuthor = "";

            return new Book
            {
                Title = "The Handy Math Answer Book",
                ISBN = "978-1578591718",
                Authors = new List<Author> { 
                    AddAuthor( "Thomas E. Svarney" ),
                    AddAuthor( "Patricia Barnes-Svarney" )
                },
                LanguageOriginal = "english",
                LanguagePublished = "english",
                Publisher = AddPublisher("Visible Ink Pr"),
                NumberOfPages = 506,
                PublicationDate = "15.9.2005",
                Subject = "Mathematics",
                Binding = "Softcover",
                Class = 7,
                DetailPageUrl = "http://www.amazon.de/Handy-Math-Answer-Book-Books/dp/1578591716/ref=sr_1_cc_1?s=books&ie=UTF8&qid=1325439602&sr=1-1-catcorr"
            };
        }

    }
}
